﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Maps.MapControl;
using MapEntities;
using System.Collections.Generic;
using System.Windows.Media.Effects;
using System.Reflection;

namespace VirtualEarth.Business
{
    public class GeoShape : GeoItem
    {
        public GeoShape(Map map, MapEntities.Shape shape)
            : base(map, shape)
        {
        }

        private List<MapPolygon> polygons = new List<MapPolygon>();

        public Color ColorFromString(string colorString)
        {
            Type colorType = (typeof(System.Windows.Media.Colors));
            if (colorType.GetProperty(colorString) != null)
            {
                object o = colorType.InvokeMember(colorString, BindingFlags.GetProperty, null, null, null); if (o != null)
                {
                    return (Color)o;
                }

            }
            return Colors.White;
        }


        private MapPolygon createPolygon(ShapeSegment segment)
        {
            MapPolygon p = new MapPolygon();            
            p.Locations = CreateLocations(segment);
            p.Fill = new SolidColorBrush(HexToColor(Item.BackgroundColor));
            p.StrokeLineJoin = PenLineJoin.Round;
            p.Opacity = GetOpacity(Item.Transparency);
            p.MouseEnter += new MouseEventHandler(p_MouseEnter);
            p.MouseLeave += new MouseEventHandler(p_MouseLeave);
            p.MouseLeftButtonUp += new MouseButtonEventHandler(p_MouseLeftButtonUp);
            p.SetValue(MapLayer.DataContextProperty, this);
            if (!string.IsNullOrEmpty(Item.Tooltip))
                ToolTipService.SetToolTip(p, Item.Tooltip);
            return p;
        }

        void p_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            Polygon p = (Polygon)e.OriginalSource;
            GeoShape shape = (GeoShape)(p.GetValue(MapLayer.DataContextProperty));
            DoBehaviour(shape.Item.Behaviour.LeftMouseClick);
        }



        void p_MouseLeave(object sender, MouseEventArgs e)
        {
            MapPolygon p = (MapPolygon)e.OriginalSource;
            GeoShape shape = (GeoShape)(p.GetValue(MapLayer.DataContextProperty));
            DoMouseLeave(shape.Item.Behaviour);
        }



        void p_MouseEnter(object sender, MouseEventArgs e)
        {
            Polygon p = (Polygon)e.OriginalSource;
            GeoShape shape = (GeoShape)(p.GetValue(MapLayer.DataContextProperty));
            DoMouseEnter(shape.Item.Behaviour);

        }

        protected override void DoMouseEnter(LayerItemBehaviour behavior)
        {
            if (behavior.ItemTransparencyLevel != TransparencyLevel.None)
            {
                foreach (MapPolygon p in this.polygons)
                {
                    p.Opacity = GetOpacity(behavior.ItemTransparencyLevel);
                }
            }

        }

        protected override void DoMouseLeave(LayerItemBehaviour behavior)
        {
            if (behavior.ItemTransparencyLevel != TransparencyLevel.None)
            {
                foreach (MapPolygon p in this.polygons)
                {
                    p.Opacity = GetOpacity(Item.Transparency);
                }
            }
        }

        private LocationCollection CreateLocations(ShapeSegment segment)
        {
            LocationCollection conn = new LocationCollection();
            foreach (GeoPoint p in segment.Points)
                conn.Add(new Location(p.Lat, p.Long));
            return conn;
        }


        private GeoPoint GetCenterGeoPoint(List<ShapeSegment> xsegment)
        {
            double xlat = 0, xlong = 0;
            int xctr = 0;

            foreach (ShapeSegment segment in xsegment)
            {
                foreach (GeoPoint xpoint in segment.Points)
                {
                    xlat += xpoint.Lat;
                    xlong += xpoint.Long;
                    xctr++;
                }
            }

            return new GeoPoint(xlat / xctr, xlong / xctr);
        }

        public override void Visualize()
        {
            polygons.Clear();
            if (!Item.Visible)
                return;


            if (!string.IsNullOrEmpty(Item.Text.Trim()))
            {
                if (Item.Segments.Count > 0)
                {
                    GeoPoint xloc = GetCenterGeoPoint(Item.Segments);
                    AddToBaseControl(GetTextBlock(Item.Text, xloc.Long, xloc.Lat));
                }
            }
            foreach (ShapeSegment segment in Item.Segments)
            {                
                MapPolygon polygon = createPolygon(segment);
                polygons.Add(polygon);
                AddToBaseControl(polygon);


            }
        }


        public new MapEntities.Shape Item
        {
            get
            {
                return (MapEntities.Shape)(base.Item);
            }
        }
    }
}
